package com.uppalz.fundmanager.dao;

import com.uppalz.fundmanager.entities.FundMember;
import java.util.Date;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

/**
 *
 * @author Zafar
 */
public class DAO {

    //*************************************/
    private static DAO _this = new DAO();

    synchronized public static DAO get() {
        if (_this == null) {
            _this = new DAO();
        }
        return _this;
    }
    //*************************************/

    private final EntityManager em;

    private DAO() {
        this.em = EMF.create();
    }

    public FundMember createNewMember(String email, String name, String contact) {
        return createNewMember(email, name, contact, null);
    }

    public FundMember createNewMember(String email, String name, String contact, Date joinDate) {
        FundMember member = new FundMember();
        member.setEmail(email);
        member.setName(name);
        member.setContactNumber(contact);
        if (joinDate == null) {
            joinDate = new Date();
        }
        member.setJoiningDate(joinDate);

        member = save(member);
        return member;
    }

    public List<FundMember> getAllMembers() {
        Query query = em.createQuery("SELECT m FROM FundMember m");
        List<FundMember> members = query.getResultList();
        return members;
    }

    public <T> T save(T object) {
        isEntity(object);
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            em.persist(object);
            tx.commit();

            em.refresh(object);
            return object;
        } catch (Exception e) {
            tx.rollback();
            throw new DataAccessException(e);
        }
    }

    public <T> T update(T object) {
        isEntity(object);
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            em.merge(object);
            tx.commit();

            em.refresh(object);
            return object;
        } catch (Exception e) {
            tx.rollback();
            throw new DataAccessException(e);
        }
    }

    private boolean isEntity(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("Object is null!");
        }
        Entity entityAnnotation = object.getClass().getAnnotation(Entity.class);
        if (entityAnnotation == null) {
            throw new IllegalArgumentException("Not an entity: " + object);
        }

        return true;
    }

}
